from rest_framework import serializers
from goods.models import SKU, SKUSpecification, GoodsCategory, SpecificationOption, SPUSpecification
from django.db import transaction
from celery_tasks.static_tasks.task import get_detail_html


class SKUSpecificationSerializer(serializers.ModelSerializer):
    """
    SKU规格表序列化器
    """
    spec_id = serializers.IntegerField(read_only=True)
    option_id = serializers.IntegerField(read_only=True)
    class Meta:
        model = SKUSpecification
        fields = ('spec_id', 'option_id')


class SKUGoodsSerializer(serializers.ModelSerializer):
    """获取sku表信息的序列化器"""

    #  指定所关联的选项信息，关联嵌套返回
    specs = SKUSpecificationSerializer(read_only=True, many=True)
    #  指定分类信息
    category_id = serializers.IntegerField()
    #  关联嵌套返回
    category = serializers.StringRelatedField(read_only=True)
    #  指定所关联的spu表信息
    spu_id = serializers.IntegerField()
    #  关联嵌套返回
    spu = serializers.StringRelatedField(read_only=True)

    class Meta:
        model = SKU
        fields = '__all__'

    def create(self, validated_data):

        specs = self.context['request'].data.get('specs')
        # del validated_data['specs']

        with transaction.atomic():
            #  开启事务
            sid = transaction.savepoint()
            try:
                #  保存sku表
                sku = SKU.objects.create(**validated_data)
                #  保存SKU具体规格
                for spec in specs:
                    SKUSpecification.objects.create(sku=sku, spec_id=spec['spec_id'],option_id=spec['option_id'])
            except:
                transaction.savepoint_rollback(sid)
                return serializers.ValidationError('数据库错误')
            else:
                transaction.savepoint_commit(sid)
                get_detail_html.delay(sku.id)
                return sku

    def update(self, instance, validated_data):
        #  获取规格信息
        specs = self.context['request'].data.get('specs')
        # del validated_data['specs']

        with transaction.atomic():
            sid = transaction.savepoint()
            try:
                SKU.objects.filter(id=instance.id).update(**validated_data)
                for spec in specs:
                    SKUSpecification.objects.create(sku=instance,spec_id=spec['spec_id'],option_id=spec['option_id'])
            except:
                transaction.savepoint_rollback(sid)
                return serializers.ValidationError('数据库错误')
            else:
                transaction.savepoint_commit(sid)
                get_detail_html.delay(instance.id)
                return instance


class SKUCategorieSerializer(serializers.ModelSerializer):
    """商品分类序列化器"""
    class Meta:
        model = GoodsCategory
        fields = '__all__'


class SPUSimpleSerializer(serializers.ModelSerializer):
    """
    商品SPU表序列化器
    """
    class Meta:
        model = GoodsCategory
        fields = ('id','name')


class SPUOptionSerializer(serializers.ModelSerializer):
    """
    规格选项序列化器
    """
    class Meta:
        model = SpecificationOption
        fields = ('id','value')
        # fields = '__all__'


class SPUSpecSerializer(serializers.ModelSerializer):
    """
    规格序列化器
    """
    #  关联序列化返回SPU表数据
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField(read_only=True)
    #  关联序列化返回，规格选项信息
    options = SPUOptionSerializer(read_only=True,many=True)

    class Meta:
        model = SPUSpecification
        fields = '__all__'


class SKUSerializer(serializers.ModelSerializer):
    """
    SKU表数据
    """
    #  返回关联spu表的名称和关联的分类表的名称
    spu = serializers.StringRelatedField(read_only=True)
    category = serializers.StringRelatedField(read_only=True)

    #  返回模型类的spu_id和category_id
    spu_id = serializers.IntegerField()
    category_id = serializers.IntegerField()

    #  返回商品的规格信息
    specs = SKUSpecificationSerializer(many=True)

    class Meta:
        model = SKU
        fields = "__all__"

